import os
import threading
import tkinter as tk
from tkinter import ttk, messagebox
from src.config import LANGUAGE_MAPPING, MODEL_PATHS
from src.utils import download_model
from src.config_manager import load_settings, save_settings


class SubtitleWindow:
    """字幕显示窗口"""
    
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("实时字幕")
        self.root.geometry("800x250")  # 增加高度确保菜单可见
        self.root.attributes('-topmost', True)  # 保持窗口置顶
        
        # 必须先初始化菜单
        self.create_proxy_menu()
        
        # 初始化语言选择变量
        self.language_var = tk.StringVar()
        
        # 初始化语言选择组件
        self._init_language_selector()
        
        # 创建样式
        self.style = ttk.Style()
        self.style.configure('TLabel', 
            font=('SimSun', 24),  # 宋体
            background='black', 
            foreground='white'
        )
        
        # 字幕标签
        self.label = ttk.Label(
            self.root,
            text="",
            wraplength=780,
            justify='center',
            style='TLabel'
        )
        self.label.pack(expand=True, fill='both')
        
        # 保证菜单可见性
        self.root.update_idletasks()

        self.cancel_flag = False  # 初始化取消标志

    def update_subtitle(self, text):
        """更新字幕内容"""
        self.label.config(text=text)
        
    def get_selected_language(self):
        """获取当前选择的语言代码"""
        lang_name = self.language_var.get()
        for code, name in LANGUAGE_MAPPING.items():
            if name == lang_name:
                if os.path.exists(MODEL_PATHS.get(code, "")):
                    return code
        # 返回第一个已安装的语言
        for code in MODEL_PATHS:
            if os.path.exists(MODEL_PATHS[code]):
                return code
        return 'en'  # 最后保底

    def show_download_dialog(self):
        """显示模型下载对话框"""
        dialog = tk.Toplevel()
        dialog.title("模型管理")
        dialog.transient(self.root)
        dialog.grab_set()
        
        # 添加关闭按钮
        ttk.Button(
            dialog,
            text="关闭窗口",
            command=lambda: [dialog.destroy(), self.check_models()]
        ).pack(side='bottom', pady=5)
        
        # 语言选择列表
        self.selected_langs = []
        for code in MODEL_PATHS:
            var = tk.BooleanVar()
            # 设置初始勾选状态
            var.set(os.path.exists(MODEL_PATHS[code]))
            chk = ttk.Checkbutton(
                dialog,
                text=f"{LANGUAGE_MAPPING[code]} ({'已安装' if os.path.exists(MODEL_PATHS[code]) else '未安装'})",
                variable=var
            )
            chk.pack(anchor='w')
            self.selected_langs.append((code, var))
        
        # 提示文本
        ttk.Label(
            dialog,
            text="请先选择并下载至少一个语言模型",
            wraplength=300
        ).pack(pady=5)
        
        # 下载按钮
        ttk.Button(
            dialog,
            text="下载选中模型",
            command=lambda: self.start_download(dialog)
        ).pack(pady=10)
        
        # 等待用户操作完成
        self.root.wait_window(dialog)
        
        # 更新语言选择器选项
        installed_models = [code for code in MODEL_PATHS if os.path.exists(MODEL_PATHS[code])]
        self.lang_selector['values'] = [LANGUAGE_MAPPING[code] for code in installed_models]
        if installed_models:
            self.lang_selector.current(0)

    def start_download(self, dialog):
        """开始下载选中的模型"""
        selected = [code for code, var in self.selected_langs if var.get()]
        if not selected:
            return
        
        # 创建进度窗口
        progress_window = tk.Toplevel()
        progress_window.title("下载进度")
        
        # 进度条
        self.progress = ttk.Progressbar(
            progress_window,
            orient='horizontal',
            length=300,
            mode='determinate'
        )
        self.progress.pack(padx=20, pady=10)
        
        # 添加取消按钮
        self.cancel_btn = ttk.Button(
            progress_window,
            text="取消下载",
            command=self.cancel_download
        )
        self.cancel_btn.pack(pady=5)
        
        # 启动下载线程
        self.download_thread = threading.Thread(
            target=self.download_models,
            args=(selected, progress_window)
        )
        self.download_thread.do_run = True
        self.download_thread.start()

    def download_models(self, langs, window):
        """执行下载任务"""
        total = len(langs)
        for i, lang in enumerate(langs):
            if self.cancel_flag:
                self.root.after(0, lambda: messagebox.showinfo("提示", "下载已取消"))
                break
            try:
                download_model(lang)
                # 更新勾选状态
                self.root.after(0, lambda l=lang: self.update_checkbox(l))
            except Exception as e:
                self.root.after(0, lambda e=e: messagebox.showerror("错误", f"{lang} 下载失败: {str(e)}"))
            
            self.progress['value'] = (i+1)/total*100
            window.update()
        
        self.root.after(0, lambda: messagebox.showinfo("完成", "所选模型下载完成"))
        window.destroy()

    def update_checkbox(self, lang_code):
        """更新指定语言的复选框状态"""
        for code, var in self.selected_langs:
            if code == lang_code:
                var.set(os.path.exists(MODEL_PATHS[code]))
                break

    def check_models(self):
        """检查是否有已安装模型"""
        available = [code for code in MODEL_PATHS if os.path.exists(MODEL_PATHS[code])]
        if not available:
            if messagebox.askyesno("提示", "尚未安装任何语言模型，是否继续下载？"):
                self.show_download_dialog()
            else:
                self.root.destroy()

    def start(self):
        """启动GUI主循环"""
        # 显示前强制更新菜单状态
        self.root.update()
        print("当前菜单状态:", self.root["menu"])
        # 检查菜单是否有效
        if not self.root["menu"]:
            messagebox.showerror("错误", "菜单初始化失败")
        self.root.mainloop()

    def create_proxy_menu(self):
        """创建顶部菜单栏"""
        menubar = tk.Menu(self.root)
        menubar.config(bg="#f0f0f0", fg="#333")
        
        setting_menu = tk.Menu(menubar, tearoff=0)
        setting_menu.config(
            bg="#ffffff", 
            activebackground="#e0e0e0",
            font=('SimSun', 10)
        )
        
        setting_menu.add_command(
            label="代理设置", 
            command=lambda: [print("菜单点击事件触发"), self.show_proxy_dialog()]
        )
        setting_menu.add_command(
            label="音频设备设置",
            command=self.show_audio_device_dialog
        )
        menubar.add_cascade(label="设置", menu=setting_menu)
        self.root.config(menu=menubar)

    def show_proxy_dialog(self):
        """显示代理设置窗口"""
        print("尝试打开代理设置...")
        try:
            settings = load_settings()
            
            dialog = tk.Toplevel(self.root)
            dialog.title("代理设置")
            dialog.transient(self.root)  # 设置为子窗口
            dialog.grab_set()  # 强制获取焦点
            
            # 代理启用复选框
            enable_var = tk.BooleanVar(value=settings['proxy']['enable'])
            ttk.Checkbutton(dialog, text="启用代理", variable=enable_var).grid(row=0, columnspan=2)
            
            # HTTP代理输入框
            ttk.Label(dialog, text="HTTP 代理:").grid(row=1, column=0, padx=5, pady=2)
            http_entry = ttk.Entry(dialog, width=30)
            http_entry.insert(0, settings['proxy']['http'])
            http_entry.grid(row=1, column=1, padx=5, pady=2)
            
            # HTTPS代理输入框
            ttk.Label(dialog, text="HTTPS 代理:").grid(row=2, column=0, padx=5, pady=2)
            https_entry = ttk.Entry(dialog, width=30)
            https_entry.insert(0, settings['proxy']['https'])
            https_entry.grid(row=2, column=1, padx=5, pady=2)
            
            # 用户名输入框
            ttk.Label(dialog, text="用户名:").grid(row=3, column=0, padx=5, pady=2)
            user_entry = ttk.Entry(dialog)
            user_entry.insert(0, settings['proxy']['username'])
            user_entry.grid(row=3, column=1, padx=5, pady=2)
            
            # 密码输入框
            ttk.Label(dialog, text="密码:").grid(row=4, column=0, padx=5, pady=2)
            pass_entry = ttk.Entry(dialog, show="*")
            pass_entry.insert(0, settings['proxy']['password'])
            pass_entry.grid(row=4, column=1, padx=5, pady=2)
            
            def save_settings_callback():
                new_settings = {
                    "proxy": {
                        "enable": enable_var.get(),
                        "http": http_entry.get(),
                        "https": https_entry.get(),
                        "username": user_entry.get(),
                        "password": pass_entry.get()
                    }
                }
                save_settings(new_settings)
                dialog.destroy()
            
            ttk.Button(dialog, text="保存", command=save_settings_callback).grid(row=5, column=0, pady=10)
            ttk.Button(dialog, text="取消", command=dialog.destroy).grid(row=5, column=1, pady=10)
            
            print("代理设置窗口已创建")
        except Exception as e:
            print(f"打开代理设置出错: {str(e)}")
            messagebox.showerror("错误", f"无法打开设置: {str(e)}")

    def show_audio_device_dialog(self):
        """显示音频设备选择窗口"""
        import sounddevice as sd
        devices = sd.query_devices()
        # 优先显示环回设备
        input_devices = [
            f"{d['name']} ({d['index']})" 
            for d in devices 
            if 'loopback' in d['name'].lower() or 'stereo mix' in d['name'].lower()
        ]
        if not input_devices:
            input_devices = [f"{d['name']} ({d['index']})" for d in devices if d['max_input_channels'] > 0]
        
        dialog = tk.Toplevel(self.root)
        dialog.title("选择音频输入设备")
        
        ttk.Label(dialog, text="选择输入设备:").pack(pady=5)
        device_var = tk.StringVar()
        device_selector = ttk.Combobox(
            dialog,
            textvariable=device_var,
            values=input_devices,
            state='readonly'
        )
        device_selector.pack(padx=10, pady=5)
        
        def save_device():
            selected = device_var.get().split('(')[-1].strip(')')
            from src.config import AUDIO_SETTINGS
            AUDIO_SETTINGS['device'] = int(selected)
            messagebox.showinfo("提示", "设备设置将在重启后生效")
            dialog.destroy()
        
        ttk.Button(dialog, text="保存", command=save_device).pack(pady=10)

    def cancel_download(self):
        """取消当前下载任务"""
        if hasattr(self, 'download_thread'):
            self.download_thread.do_run = False
        self.cancel_flag = True 

    def _init_language_selector(self):
        """初始化语言选择组件"""
        # 创建底部控制面板
        control_frame = ttk.Frame(self.root)
        control_frame.pack(side='bottom', fill='x', padx=10, pady=10)
        
        # 语言选择框
        self.lang_selector = ttk.Combobox(
            control_frame,
            textvariable=self.language_var,
            values=list(LANGUAGE_MAPPING.values()),
            state='readonly',
            width=25
        )
        self.lang_selector.grid(row=0, column=0, padx=5, sticky='ew')
        
        # 管理模型按钮
        self.download_btn = ttk.Button(
            control_frame,
            text="管理模型",
            command=self.show_download_dialog,
            width=15
        )
        self.download_btn.grid(row=0, column=1, padx=5)
        
        # 设置列权重
        control_frame.columnconfigure(0, weight=1)
        self.lang_selector.current(0) 